home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / EXAMPLES / SURFGRID.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  15.3 KB  |  589 lines

  1. /**
  2.  * surfgrid.c - simple test of polygon offset
  3.  *
  4.  * GLUT distribution version  $Revision: 1.8 $
  5.  *
  6.  * usage:
  7.  *    surfgrid [-f]
  8.  *
  9.  * options:
  10.  *    -f    run on full screen
  11.  *
  12.  * keys:
  13.  *    p    toggle polygon offset
  14.  *      F       increase polygon offset factor
  15.  *      f       decrease polygon offset factor
  16.  *      B       increase polygon offset bias
  17.  *      b       decrease polygon offset bias
  18.  *    g    toggle grid drawing
  19.  *    s    toggle smooth/flat shading
  20.  *    n    toggle whether to use GL evaluators or GLU nurbs
  21.  *    u    decr number of segments in U direction
  22.  *    U    incr number of segments in U direction
  23.  *    v    decr number of segments in V direction
  24.  *    V    incr number of segments in V direction
  25.  *    escape    quit
  26.  */
  27.  
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <stdlib.h>
  31. #include <math.h>
  32. #include <GL/glut.h>
  33.  
  34. #define W 600
  35. #define H 600
  36.  
  37. float z_axis[] =
  38. {0.0, 0.0, 1.0};
  39.  
  40. void
  41. norm(float v[3])
  42. {
  43.   float r;
  44.  
  45.   r = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  46.  
  47.   v[0] /= r;
  48.   v[1] /= r;
  49.   v[2] /= r;
  50. }
  51.  
  52. void
  53. cross(float v1[3], float v2[3], float result[3])
  54. {
  55.   result[0] = v1[1] * v2[2] - v1[2] * v2[1];
  56.   result[1] = v1[2] * v2[0] - v1[0] * v2[2];
  57.   result[2] = v1[0] * v2[1] - v1[1] * v2[0];
  58. }
  59.  
  60. float
  61. length(float v[3])
  62. {
  63.   float r = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
  64.   return r;
  65. }
  66.  
  67. static int winwidth = W, winheight = H;
  68. GLUnurbsObj *nobj;
  69. GLuint surflist, gridlist;
  70.  
  71. int useglunurbs = 0;
  72. int smooth = 1;
  73. GLboolean tracking = GL_FALSE;
  74. int showgrid = 1;
  75. int showsurf = 1;
  76. int fullscreen = 0;
  77. float modelmatrix[16];
  78. float factor = 0.5;
  79. float bias = 0.002;
  80. int usegments = 4;
  81. int vsegments = 4;
  82.  
  83. int spindx, spindy;
  84. int startx, starty;
  85. int curx, cury;
  86. int prevx, prevy;       /* to get good deltas using glut */
  87.  
  88. void redraw(void);
  89. void createlists(void);
  90.  
  91. /* Control points of the torus in Bezier form.  Can be rendered
  92.    using OpenGL evaluators. */
  93. static GLfloat torusbezierpts[] =
  94. {
  95. /* *INDENT-OFF* */
  96.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 3.0, 0.0, 1.0, 2.0,
  97.    3.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0,
  98.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 3.0, 0.0,-1.0, 2.0,
  99.    3.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0,
  100.    2.0,-2.0, 0.0, 2.0, 1.0,-1.0, 0.5, 1.0, 1.5,-1.5, 0.5, 1.0,
  101.    1.5,-1.5, 0.5, 1.0, 2.0,-2.0, 0.5, 1.0, 4.0,-4.0, 0.0, 2.0,
  102.    4.0,-4.0, 0.0, 2.0, 2.0,-2.0,-0.5, 1.0, 1.5,-1.5,-0.5, 1.0,
  103.    1.5,-1.5,-0.5, 1.0, 1.0,-1.0,-0.5, 1.0, 2.0,-2.0, 0.0, 2.0,
  104.    0.0,-2.0, 0.0, 2.0, 0.0,-1.0, 0.5, 1.0, 0.0,-1.5, 0.5, 1.0,
  105.    0.0,-1.5, 0.5, 1.0, 0.0,-2.0, 0.5, 1.0, 0.0,-4.0, 0.0, 2.0,
  106.    0.0,-4.0, 0.0, 2.0, 0.0,-2.0,-0.5, 1.0, 0.0,-1.5,-0.5, 1.0,
  107.    0.0,-1.5,-0.5, 1.0, 0.0,-1.0,-0.5, 1.0, 0.0,-2.0, 0.0, 2.0,
  108.    0.0,-2.0, 0.0, 2.0, 0.0,-1.0, 0.5, 1.0, 0.0,-1.5, 0.5, 1.0,
  109.    0.0,-1.5, 0.5, 1.0, 0.0,-2.0, 0.5, 1.0, 0.0,-4.0, 0.0, 2.0,
  110.    0.0,-4.0, 0.0, 2.0, 0.0,-2.0,-0.5, 1.0, 0.0,-1.5,-0.5, 1.0,
  111.    0.0,-1.5,-0.5, 1.0, 0.0,-1.0,-0.5, 1.0, 0.0,-2.0, 0.0, 2.0,
  112.   -2.0,-2.0, 0.0, 2.0,-1.0,-1.0, 0.5, 1.0,-1.5,-1.5, 0.5, 1.0,
  113.   -1.5,-1.5, 0.5, 1.0,-2.0,-2.0, 0.5, 1.0,-4.0,-4.0, 0.0, 2.0,
  114.   -4.0,-4.0, 0.0, 2.0,-2.0,-2.0,-0.5, 1.0,-1.5,-1.5,-0.5, 1.0,
  115.   -1.5,-1.5,-0.5, 1.0,-1.0,-1.0,-0.5, 1.0,-2.0,-2.0, 0.0, 2.0,
  116.   -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-3.0, 0.0, 1.0, 2.0,
  117.   -3.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,-8.0, 0.0, 0.0, 4.0,
  118.   -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-3.0, 0.0,-1.0, 2.0,
  119.   -3.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,-4.0, 0.0, 0.0, 4.0,
  120.   -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-3.0, 0.0, 1.0, 2.0,
  121.   -3.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,-8.0, 0.0, 0.0, 4.0,
  122.   -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-3.0, 0.0,-1.0, 2.0,
  123.   -3.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,-4.0, 0.0, 0.0, 4.0,
  124.   -2.0, 2.0, 0.0, 2.0,-1.0, 1.0, 0.5, 1.0,-1.5, 1.5, 0.5, 1.0,
  125.   -1.5, 1.5, 0.5, 1.0,-2.0, 2.0, 0.5, 1.0,-4.0, 4.0, 0.0, 2.0,
  126.   -4.0, 4.0, 0.0, 2.0,-2.0, 2.0,-0.5, 1.0,-1.5, 1.5,-0.5, 1.0,
  127.   -1.5, 1.5,-0.5, 1.0,-1.0, 1.0,-0.5, 1.0,-2.0, 2.0, 0.0, 2.0,
  128.    0.0, 2.0, 0.0, 2.0, 0.0, 1.0, 0.5, 1.0, 0.0, 1.5, 0.5, 1.0,
  129.    0.0, 1.5, 0.5, 1.0, 0.0, 2.0, 0.5, 1.0, 0.0, 4.0, 0.0, 2.0,
  130.    0.0, 4.0, 0.0, 2.0, 0.0, 2.0,-0.5, 1.0, 0.0, 1.5,-0.5, 1.0,
  131.    0.0, 1.5,-0.5, 1.0, 0.0, 1.0,-0.5, 1.0, 0.0, 2.0, 0.0, 2.0,
  132.    0.0, 2.0, 0.0, 2.0, 0.0, 1.0, 0.5, 1.0, 0.0, 1.5, 0.5, 1.0,
  133.    0.0, 1.5, 0.5, 1.0, 0.0, 2.0, 0.5, 1.0, 0.0, 4.0, 0.0, 2.0,
  134.    0.0, 4.0, 0.0, 2.0, 0.0, 2.0,-0.5, 1.0, 0.0, 1.5,-0.5, 1.0,
  135.    0.0, 1.5,-0.5, 1.0, 0.0, 1.0,-0.5, 1.0, 0.0, 2.0, 0.0, 2.0,
  136.    2.0, 2.0, 0.0, 2.0, 1.0, 1.0, 0.5, 1.0, 1.5, 1.5, 0.5, 1.0,
  137.    1.5, 1.5, 0.5, 1.0, 2.0, 2.0, 0.5, 1.0, 4.0, 4.0, 0.0, 2.0,
  138.    4.0, 4.0, 0.0, 2.0, 2.0, 2.0,-0.5, 1.0, 1.5, 1.5,-0.5, 1.0,
  139.    1.5, 1.5,-0.5, 1.0, 1.0, 1.0,-0.5, 1.0, 2.0, 2.0, 0.0, 2.0,
  140.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 3.0, 0.0, 1.0, 2.0,
  141.    3.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0, 8.0, 0.0, 0.0, 4.0,
  142.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 3.0, 0.0,-1.0, 2.0,
  143.    3.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0, 4.0, 0.0, 0.0, 4.0,
  144. /* *INDENT-ON* */
  145.  
  146. };
  147.  
  148. /* Control points of a torus in NURBS form.  Can be rendered using
  149.    the GLU NURBS routines. */
  150. static GLfloat torusnurbpts[] =
  151. {
  152. /* *INDENT-OFF* */
  153.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0,
  154.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0,
  155.    4.0, 0.0, 0.0, 4.0, 2.0,-2.0, 0.0, 2.0, 1.0,-1.0, 0.5, 1.0,
  156.    2.0,-2.0, 0.5, 1.0, 4.0,-4.0, 0.0, 2.0, 2.0,-2.0,-0.5, 1.0,
  157.    1.0,-1.0,-0.5, 1.0, 2.0,-2.0, 0.0, 2.0,-2.0,-2.0, 0.0, 2.0,
  158.   -1.0,-1.0, 0.5, 1.0,-2.0,-2.0, 0.5, 1.0,-4.0,-4.0, 0.0, 2.0,
  159.   -2.0,-2.0,-0.5, 1.0,-1.0,-1.0,-0.5, 1.0,-2.0,-2.0, 0.0, 2.0,
  160.   -4.0, 0.0, 0.0, 4.0,-2.0, 0.0, 1.0, 2.0,-4.0, 0.0, 1.0, 2.0,
  161.   -8.0, 0.0, 0.0, 4.0,-4.0, 0.0,-1.0, 2.0,-2.0, 0.0,-1.0, 2.0,
  162.   -4.0, 0.0, 0.0, 4.0,-2.0, 2.0, 0.0, 2.0,-1.0, 1.0, 0.5, 1.0,
  163.   -2.0, 2.0, 0.5, 1.0,-4.0, 4.0, 0.0, 2.0,-2.0, 2.0,-0.5, 1.0,
  164.   -1.0, 1.0,-0.5, 1.0,-2.0, 2.0, 0.0, 2.0, 2.0, 2.0, 0.0, 2.0,
  165.    1.0, 1.0, 0.5, 1.0, 2.0, 2.0, 0.5, 1.0, 4.0, 4.0, 0.0, 2.0,
  166.    2.0, 2.0,-0.5, 1.0, 1.0, 1.0,-0.5, 1.0, 2.0, 2.0, 0.0, 2.0,
  167.    4.0, 0.0, 0.0, 4.0, 2.0, 0.0, 1.0, 2.0, 4.0, 0.0, 1.0, 2.0,
  168.    8.0, 0.0, 0.0, 4.0, 4.0, 0.0,-1.0, 2.0, 2.0, 0.0,-1.0, 2.0,
  169.    4.0, 0.0, 0.0, 4.0,
  170. /* *INDENT-ON* */
  171.  
  172. };
  173.  
  174. void
  175. move(int x, int y)
  176. {
  177.   prevx = curx;
  178.   prevy = cury;
  179.   curx = x;
  180.   cury = y;
  181.   if (curx != startx || cury != starty) {
  182.     glutPostRedisplay();
  183.     startx = curx;
  184.     starty = cury;
  185.   }
  186. }
  187.  
  188. void
  189. button(int button, int state, int x, int y)
  190. {
  191.   if (button != GLUT_LEFT_BUTTON)
  192.     return;
  193.   switch (state) {
  194.   case GLUT_DOWN:
  195.     prevx = curx = startx = x;
  196.     prevy = cury = starty = y;
  197.     spindx = 0;
  198.     spindy = 0;
  199.     tracking = GL_TRUE;
  200.     break;
  201.   case GLUT_UP:
  202.     /* 
  203.      * If user released the button while moving the mouse, keep
  204.      * spinning.
  205.      */
  206.     if (x != prevx || y != prevy) {
  207.       spindx = x - prevx;
  208.       spindy = y - prevy;
  209.     }
  210.     tracking = GL_FALSE;
  211.     break;
  212.   }
  213. }
  214.  
  215. /* Maintain a square window when resizing */
  216. void
  217. reshape(int width, int height)
  218. {
  219.   int size;
  220.   size = (width < height ? width : height);
  221.   glViewport((width - size) / 2, (height - size) / 2, size, size);
  222.   glutReshapeWindow(size, size);
  223.   glutPostRedisplay();
  224. }
  225.  
  226. void
  227. gridmaterials(void)
  228. {
  229.   static float front_mat_diffuse[] =
  230.   {1.0, 1.0, 0.4, 1.0};
  231.   static float front_mat_ambient[] =
  232.   {0.1, 0.1, 0.1, 1.0};
  233.   static float back_mat_diffuse[] =
  234.   {1.0, 0.0, 0.0, 1.0};
  235.   static float back_mat_ambient[] =
  236.   {0.1, 0.1, 0.1, 1.0};
  237.  
  238.   glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  239.   glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
  240.   glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  241.   glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
  242. }
  243.  
  244. void
  245. surfacematerials(void)
  246. {
  247.   static float front_mat_diffuse[] =
  248.   {0.2, 0.7, 0.4, 1.0};
  249.   static float front_mat_ambient[] =
  250.   {0.1, 0.1, 0.1, 1.0};
  251.   static float back_mat_diffuse[] =
  252.   {1.0, 1.0, 0.2, 1.0};
  253.   static float back_mat_ambient[] =
  254.   {0.1, 0.1, 0.1, 1.0};
  255.  
  256.   glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
  257.   glMaterialfv(GL_FRONT, GL_AMBIENT, front_mat_ambient);
  258.   glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
  259.   glMaterialfv(GL_BACK, GL_AMBIENT, back_mat_ambient);
  260. }
  261.  
  262. void
  263. init(void)
  264. {
  265.   static float ambient[] =
  266.   {0.0, 0.0, 0.0, 1.0};
  267.   static float diffuse[] =
  268.   {1.0, 1.0, 1.0, 1.0};
  269.   static float position[] =
  270.   {90.0, 90.0, -150.0, 0.0};
  271.   static float lmodel_ambient[] =
  272.   {1.0, 1.0, 1.0, 1.0};
  273.  
  274.   glMatrixMode(GL_PROJECTION);
  275.   glLoadIdentity();
  276.   gluPerspective(40.0, 1.0, 2.0, 200.0);
  277.   glMatrixMode(GL_MODELVIEW);
  278.   glLoadIdentity();
  279.   glGetFloatv(GL_MODELVIEW_MATRIX, modelmatrix);
  280.  
  281.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  282.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  283.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  284.   glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  285.  
  286.   glEnable(GL_LIGHTING);
  287.   glEnable(GL_LIGHT0);
  288.   glEnable(GL_DEPTH_TEST);
  289.   glEnable(GL_AUTO_NORMAL);
  290.   glFrontFace(GL_CCW);
  291.  
  292.   glEnable(GL_MAP2_VERTEX_4);
  293.   glClearColor(0.25, 0.25, 0.5, 0.0);
  294.  
  295. #if GL_EXT_polygon_offset
  296.   glPolygonOffsetEXT(factor, bias);
  297.   glEnable(GL_POLYGON_OFFSET_EXT);
  298. #endif
  299.  
  300.   nobj = gluNewNurbsRenderer();
  301. #ifdef GLU_VERSION_1_1  /* New GLU 1.1 interface. */
  302.   gluNurbsProperty(nobj, GLU_SAMPLING_METHOD, GLU_DOMAIN_DISTANCE);
  303. #endif
  304.  
  305.   surflist = glGenLists(1);
  306.   gridlist = glGenLists(1);
  307.   createlists();
  308. }
  309.  
  310. void
  311. drawmesh(void)
  312. {
  313.   int i, j;
  314.   float *p;
  315.  
  316.   int up2p = 4;
  317.   int uorder = 3, vorder = 3;
  318.   int nu = 4, nv = 4;
  319.   int vp2p = up2p * uorder * nu;
  320.  
  321.   for (j = 0; j < nv; j++) {
  322.     for (i = 0; i < nu; i++) {
  323.       p = torusbezierpts + (j * vp2p * vorder) + (i * up2p * uorder);
  324. #if GL_EXT_polygon_offset
  325.       glPolygonOffsetEXT(factor, bias);
  326. #endif
  327.       glMap2f(GL_MAP2_VERTEX_4, 0.0, 1.0, up2p, 3, 0.0, 1.0, vp2p, 3,
  328.         (void *) p);
  329.       if (showsurf) {
  330.         surfacematerials();
  331.         glEvalMesh2(GL_FILL, 0, usegments, 0, vsegments);
  332.       }
  333.       if (showgrid) {
  334.         gridmaterials();
  335.         glEvalMesh2(GL_LINE, 0, usegments, 0, vsegments);
  336.       }
  337.     }
  338.   }
  339. }
  340.  
  341. void
  342. redraw(void)
  343. {
  344.   int dx, dy;
  345.   float v[3], rot[3];
  346.   float len, ang;
  347.  
  348.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  349.   glColor3f(1, 0, 0);
  350.  
  351.   if (tracking) {
  352.     dx = curx - startx;
  353.     dy = cury - starty;
  354.   } else {
  355.     dx = spindx;
  356.     dy = spindy;
  357.   }
  358.   if (dx || dy) {
  359.     dy = -dy;
  360.     v[0] = dx;
  361.     v[1] = dy;
  362.     v[2] = 0;
  363.  
  364.     len = length(v);
  365.     ang = -len / 600 * 360;
  366.     norm(v);
  367.     cross(v, z_axis, rot);
  368.  
  369.     /* This is certainly not recommended for programs that care
  370.        about performance or numerical stability: we concatenate
  371.        the rotation onto the current modelview matrix and read
  372.        the matrix back, thus saving ourselves from writing our
  373.        own matrix manipulation routines.  */
  374.     glLoadIdentity();
  375.     glRotatef(ang, rot[0], rot[1], rot[2]);
  376.     glMultMatrixf(modelmatrix);
  377.     glGetFloatv(GL_MODELVIEW_MATRIX, modelmatrix);
  378.   }
  379.   glLoadIdentity();
  380.   glTranslatef(0.0, 0.0, -10.0);
  381.   glMultMatrixf(modelmatrix);
  382.  
  383.   if (useglunurbs) {
  384.     if (showsurf)
  385.       glCallList(surflist);
  386.     if (showgrid)
  387.       glCallList(gridlist);
  388.   } else {
  389.     glMapGrid2f(usegments, 0.0, 1.0, vsegments, 0.0, 1.0);
  390.     drawmesh();
  391.   }
  392.  
  393.   glutSwapBuffers();
  394. }
  395.  
  396. static void
  397. usage(void)
  398. {
  399.   printf("usage: surfgrid [-f]\n");
  400.   exit(-1);
  401. }
  402.  
  403. /* what to do when a menu item is selected. This function also handles
  404.    keystroke events.  */
  405. void
  406. menu(int item)
  407. {
  408.   switch (item) {
  409.   case 'p':
  410. #if GL_EXT_polygon_offset
  411.     if (glIsEnabled(GL_POLYGON_OFFSET_EXT)) {
  412.       glDisable(GL_POLYGON_OFFSET_EXT);
  413.       printf("disabling polygon offset\n");
  414.     } else {
  415.       glEnable(GL_POLYGON_OFFSET_EXT);
  416.       printf("enabling polygon offset\n");
  417.     }
  418. #endif
  419.     break;
  420.   case 'F':
  421.     factor += 0.1;
  422.     printf("factor: %8.4f\n", factor);
  423.     break;
  424.   case 'f':
  425.     factor -= 0.1;
  426.     printf("factor: %8.4f\n", factor);
  427.     break;
  428.   case 'B':
  429.     bias += 0.0001;
  430.     printf("bias:  %8.4f\n", bias);
  431.     break;
  432.   case 'b':
  433.     bias -= 0.0001;
  434.     printf("bias:  %8.4f\n", bias);
  435.     break;
  436.   case 'g':
  437.     showgrid = !showgrid;
  438.     break;
  439.   case 'n':
  440.     useglunurbs = !useglunurbs;
  441.     break;
  442.   case 's':
  443.     smooth = !smooth;
  444.     if (smooth) {
  445.       glShadeModel(GL_SMOOTH);
  446.     } else {
  447.       glShadeModel(GL_FLAT);
  448.     }
  449.     break;
  450.   case 't':
  451.     showsurf = !showsurf;
  452.     break;
  453.   case 'u':
  454.     usegments = (usegments < 2 ? 1 : usegments - 1);
  455.     createlists();
  456.     break;
  457.   case 'U':
  458.     usegments++;
  459.     createlists();
  460.     break;
  461.   case 'v':
  462.     vsegments = (vsegments < 2 ? 1 : vsegments - 1);
  463.     createlists();
  464.     break;
  465.   case 'V':
  466.     vsegments++;
  467.     createlists();
  468.     break;
  469.   case '\033':         /* ESC key: quit */
  470.     exit(0);
  471.     break;
  472.   }
  473.   glutPostRedisplay();
  474. }
  475.  
  476. /* ARGSUSED1 */
  477. void
  478. key(unsigned char key, int x, int y)
  479. {
  480.   menu((int) key);
  481. }
  482.  
  483. void
  484. animate(void)
  485. {
  486.   if (!tracking && (spindx != 0 || spindy != 0))
  487.     glutPostRedisplay();
  488. }
  489.  
  490. int
  491. main(int argc, char **argv)
  492. {
  493.   int i;
  494.  
  495.   glutInit(&argc, argv);  /* initialize glut, processing
  496.                              arguments */
  497.  
  498.   for (i = 1; i < argc; i++) {
  499.     if (argv[i][0] == '-') {
  500.       switch (argv[i][1]) {
  501.       case 'f':
  502.         fullscreen = 1;
  503.         break;
  504.       default:
  505.         usage();
  506.         break;
  507.       }
  508.     } else {
  509.       usage();
  510.     }
  511.   }
  512.  
  513.   glutInitWindowSize(winwidth, winheight);
  514.   glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
  515.   glutCreateWindow("surfgrid");
  516.  
  517.   /* create a menu for the right mouse button */
  518.   glutCreateMenu(menu);
  519. #if GL_EXT_polygon_offset
  520.   glutAddMenuEntry("p: toggle polygon offset", 'p');
  521. #endif
  522.   glutAddMenuEntry("F: increase factor", 'F');
  523.   glutAddMenuEntry("f: decrease factor", 'f');
  524.   glutAddMenuEntry("B: increase bias", 'B');
  525.   glutAddMenuEntry("b: decrease bias", 'b');
  526.   glutAddMenuEntry("g: toggle grid", 'g');
  527.   glutAddMenuEntry("s: toggle smooth shading", 's');
  528.   glutAddMenuEntry("t: toggle surface", 't');
  529.   glutAddMenuEntry("n: toggle GL evalutators/GLU nurbs", 'n');
  530.   glutAddMenuEntry("u: decrement u segments", 'u');
  531.   glutAddMenuEntry("U: increment u segments", 'U');
  532.   glutAddMenuEntry("v: decrement v segments", 'v');
  533.   glutAddMenuEntry("V: increment v segments", 'V');
  534.   glutAddMenuEntry("<esc>: exit program", '\033');
  535.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  536.  
  537.   /* set callbacks */
  538.   glutKeyboardFunc(key);
  539.   glutDisplayFunc(redraw);
  540.   glutReshapeFunc(reshape);
  541.   glutMouseFunc(button);
  542.   glutMotionFunc(move);
  543.   glutIdleFunc(animate);
  544.  
  545. #if GL_EXT_polygon_offset
  546.   if (!glutExtensionSupported("GL_EXT_polygon_offset")) {
  547.     printf("Warning: "
  548.       "GL_EXT_polygon_offset not supported on this machine... "
  549.       "trying anyway\n");
  550.   }
  551. #else
  552.   printf("Warning: not compiled with GL_EXT_polygon_offset support.\n");
  553. #endif
  554.  
  555.   init();
  556.   glutMainLoop();
  557.   return 0;             /* ANSI C requires main to return int. */
  558. }
  559.  
  560. float circleknots[] =
  561. {0.0, 0.0, 0.0, 0.25, 0.50, 0.50, 0.75, 1.0, 1.0, 1.0};
  562.  
  563. void
  564. createlists(void)
  565. {
  566. #ifdef GLU_VERSION_1_1  /* New GLU 1.1 interface. */
  567.   gluNurbsProperty(nobj, GLU_U_STEP, (usegments - 1) * 4);
  568.   gluNurbsProperty(nobj, GLU_V_STEP, (vsegments - 1) * 4);
  569.  
  570.   gluNurbsProperty(nobj, GLU_DISPLAY_MODE, GLU_FILL);
  571. #endif
  572.   glNewList(surflist, GL_COMPILE);
  573.   surfacematerials();
  574.   gluBeginSurface(nobj);
  575.   gluNurbsSurface(nobj, 10, circleknots, 10, circleknots,
  576.     4, 28, torusnurbpts, 3, 3, GL_MAP2_VERTEX_4);
  577.   gluEndSurface(nobj);
  578.   glEndList();
  579.  
  580.   gluNurbsProperty(nobj, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
  581.   glNewList(gridlist, GL_COMPILE);
  582.   gridmaterials();
  583.   gluBeginSurface(nobj);
  584.   gluNurbsSurface(nobj, 10, circleknots, 10, circleknots,
  585.     4, 28, torusnurbpts, 3, 3, GL_MAP2_VERTEX_4);
  586.   gluEndSurface(nobj);
  587.   glEndList();
  588. }
  589.